package com.youlu.campus.admin.vote.service;

import com.mongodb.client.result.UpdateResult;
import com.youlu.campus.admin.vote.dto.ProvinceSearchDTO;
import com.youlu.campus.admin.vote.dto.VoteOrgOpDTO;
import com.youlu.campus.admin.vote.dto.VoteOrgSaveDTO;
import com.youlu.campus.admin.vote.dto.VoteOrgSearchDTO;
import com.youlu.campus.base.exception.BusinessException;
import com.youlu.campus.entity.UniversityInfo;
import com.youlu.campus.entity.enums.OrgTypeEnum;
import com.youlu.campus.entity.vote.OrganizationType;
import com.youlu.campus.entity.vote.ProvinceBaseEntity;
import com.youlu.campus.entity.vote.VoteOrganizationInfo;
import com.youlu.campus.entity.vote.VoteSimpleActivityEntity;
import com.youlu.campus.service.course.QueryWrapper;
import com.youlu.campus.service.vote.ActivityVoteRedisService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author : [dengbo]
 * @className : VoteOrgService
 * @description : [投票组织类]
 * @createTime : [2022/7/5 13:39]
 */
@Service
@Slf4j
public class VoteOrgService {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private ActivityVoteRedisService activityVoteRedisService;

    public boolean save(VoteOrgSaveDTO saveDTO) {
        OrganizationType organizationType = mongoTemplate.findById(saveDTO.getOrgTypeId(), OrganizationType.class);
        if (organizationType == null) {
            throw new BusinessException("组织类型Id不存在");
        }
        VoteOrganizationInfo info = null;
        boolean insert = true;
        if (StringUtils.isNotBlank(saveDTO.getId())) {
            info = mongoTemplate.findById(saveDTO.getId(), VoteOrganizationInfo.class);
            if (info == null) {
                throw new BusinessException("修改信息不存在");
            }
            insert = false;
        } else {
            info = new VoteOrganizationInfo();
            info.setTotalVoteNum(0L);
            info.setRealVoteNum(0L);
        }
        Query existQuery = new Query(Criteria.where("orgTypeId").is(saveDTO.getOrgTypeId()).and("orgCode").is(saveDTO.getOrgCode()));
        if (!insert) {
            existQuery.addCriteria(Criteria.where("id").ne(info.getId()));
        }
        boolean exist = mongoTemplate.exists(existQuery, VoteOrganizationInfo.class);
        if (exist) {
            throw new BusinessException("组织编码选手已经添加");
        }
        if (OrgTypeEnum.SCHOOL.getType() == organizationType.getOrgType()) {
            Query query = new Query(Criteria.where("value").is(saveDTO.getOrgCode()));
            UniversityInfo universityInfo = mongoTemplate.findOne(query, UniversityInfo.class);
            if (universityInfo == null) {
                throw new BusinessException("组织编码对应学校信息不存在");
            }
            info.setOrgId(universityInfo.getId());
        }
        info.setOrgCode(saveDTO.getOrgCode());
        info.setOrgLogo(saveDTO.getOrgLogo());
        info.setOrgTypeId(saveDTO.getOrgTypeId());
        info.setOrgName(saveDTO.getOrgName());
        info.setProvince(saveDTO.getProvince());
        info.setProvinceCode(saveDTO.getProvinceCode());
        mongoTemplate.save(info);
        return true;
    }

    public Page<VoteOrganizationInfo> search(VoteOrgSearchDTO dto) {
        QueryWrapper query = new QueryWrapper();
        query.where("orgTypeId", dto.getOrgTypeId());
        if (StringUtils.isNotBlank(dto.getOrgCode())) {
            query.where("orgCode", dto.getOrgCode());
        }
        if (StringUtils.isNotBlank(dto.getOrgName())) {
            query.like("orgName", dto.getOrgName());
        }
        query.addCriteria(Criteria.where("deleted").ne(true));
        long count = mongoTemplate.count(query, VoteOrganizationInfo.class);
        query.with(Sort.by(Sort.Order.desc("createdTime")));
        PageRequest pageRequest = PageRequest.of(dto.getPage() - 1, dto.getPageSize());
        List<VoteOrganizationInfo> data = mongoTemplate.find(query.with(pageRequest), VoteOrganizationInfo.class);
        return PageableExecutionUtils.getPage(data, pageRequest, () -> count);
    }

    public Page<ProvinceBaseEntity> provinceSearch(ProvinceSearchDTO dto) {
        QueryWrapper query = new QueryWrapper();
        if (StringUtils.isNotBlank(dto.getCode())) {
            query.where("code", dto.getCode());
        }
        if (StringUtils.isNotBlank(dto.getName())) {
            query.like("name", dto.getName());
        }
        long count = mongoTemplate.count(query, ProvinceBaseEntity.class);
        query.with(Sort.by(Sort.Order.asc("id")));
        PageRequest pageRequest = PageRequest.of(dto.getPage() - 1, dto.getPageSize());
        List<ProvinceBaseEntity> data = mongoTemplate.find(query.with(pageRequest), ProvinceBaseEntity.class);
        return PageableExecutionUtils.getPage(data, pageRequest, () -> count);
    }

    public boolean operation(VoteOrgOpDTO dto) {
        VoteOrganizationInfo info = mongoTemplate.findById(dto.getId(), VoteOrganizationInfo.class);
        if (info == null) {
            throw new BusinessException("选手信息不存在");
        }
        // 查询活动信息
        QueryWrapper activeQuery = new QueryWrapper();
        activeQuery.select("id", "orgTypeId");
        activeQuery.where("orgTypeId", info.getOrgTypeId());
        VoteSimpleActivityEntity activityInfo = mongoTemplate.findOne(activeQuery, VoteSimpleActivityEntity.class);
        if (activityInfo == null) {
            throw new BusinessException("活动信息不存在");
        }
        long totalVoteNum = info.getTotalVoteNum();
        if (totalVoteNum + dto.getNum() < 0) {
            throw new BusinessException("投票总数不能小于0");
        }
        Query query = new Query(Criteria.where("id").is(dto.getId()));
        Update update = new Update();
        if (dto.getNum() < 0) {
            query.addCriteria(Criteria.where("totalVoteNum").gte(-dto.getNum()));
        }
        update.inc("totalVoteNum", dto.getNum());
        UpdateResult result = mongoTemplate.updateFirst(query, update, VoteOrganizationInfo.class);
        if (result.getModifiedCount() > 0) {
            // 更新redis全国排行榜数据
            activityVoteRedisService.incAllSchoolVote(activityInfo.getId(), info.getOrgCode(), dto.getNum());
            // 更新redis省榜排行榜数据
            activityVoteRedisService.incProvinceSchoolVote(activityInfo.getId(), info.getProvinceCode(), info.getOrgCode(), dto.getNum());
            // 添加总的投票数量
            activityVoteRedisService.incTotalVoteNum(activityInfo.getId(),dto.getNum());
        }
        return true;
    }
}
